package cn.blog.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import cn.blog.common.PublicResultJosn;
import cn.blog.dto.LoginUser;
import cn.blog.dto.Token;
import cn.blog.filter.TokenFilter;
import cn.blog.service.TokenService;
import cn.blog.utils.ResponseUtil;

/**
 * 登录处理handler
 * 
 * @author 偶尔有点困
 * @date 2018年5月5日
 */
@Configuration
public class SecurityHandlerConfig {

	@Autowired
	private TokenService tokenService;

	/**
	 * 登录成功
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationSuccessHandler loginSuccess() {
		return new AuthenticationSuccessHandler() {
			@Override
			public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				LoginUser user = (LoginUser) authentication.getPrincipal();
				String t = TokenFilter.getToken(request);
				LoginUser loginUser = tokenService.getLoginUser(t);
				Token token;
				if (null == loginUser) {
					// 登录token无效
					token = tokenService.saveToken(user);
				} else {
					token = new Token(t, loginUser.getLogintime());
				}
				ResponseUtil.responseJson(response, HttpStatus.OK.value(),
						new PublicResultJosn(HttpStatus.OK.value(), "登录成功", token));
			}
		};
	}

	/**
	 * 登录失败
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationFailureHandler loginFailure() {
		return new AuthenticationFailureHandler() {
			@Override
			public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException exception) throws IOException, ServletException {
				String msg = null;
				if (exception instanceof BadCredentialsException) {
					msg = "用户名或密码错误";
				} else {
					msg = exception.getMessage();
				}
				ResponseUtil.responseJson(response, HttpStatus.BAD_REQUEST.value(),
						new PublicResultJosn(HttpStatus.BAD_REQUEST.value(), msg, null));
			}
		};
	}

	/**
	 * 未登录
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationEntryPoint authenticationEntryPoint() {
		return new AuthenticationEntryPoint() {
			@Override
			public void commence(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException authException) throws IOException, ServletException {
				ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(),
						new PublicResultJosn(HttpStatus.UNAUTHORIZED.value(), "请先登录", null));
			}
		};
	}

	/**
	 * 退出登录
	 * 
	 * @return
	 */
	@Bean
	public LogoutSuccessHandler logoutSuccessHandler() {
		return new LogoutSuccessHandler() {
			@Override
			public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				String token = TokenFilter.getToken(request);
				tokenService.deleteToken(token);
				ResponseUtil.responseJson(response, HttpStatus.OK.value(),
						new PublicResultJosn(HttpStatus.OK.value(), "退出成功", null));

			}
		};
	}
}